/**
 * 20220304:[require] to [import]...jordia
 */
import {BufferGeometry,BufferAttribute} from 'three';

/**
 * 圆形几何体
 *
 * thetaSegments: 弧形段数（仅实例化时有用）
 * thetaStart：起始角度（弧度）
 * thetaLength：扇形角度（弧度）
 * radius：半径
 *
 * 示意代码：
 let g=new CircleGeometry({
        thetaSegments:64,
        thetaStart:0,
        thetaLength:5,
    });
 let m=new MeshBasicMaterial({
        side:FrontSide,
        transparent:true,
        opacity:0.3
    });
 let mm=new Mesh(g,m);
 scene.add(mm);

 let t=5;
 setInterval(()=>{
        t-=0.01;
        t=t<0?6.28:t;
        g.thetaLength=t;
    },50);
 */
export default class CircleGeometry extends BufferGeometry{
    constructor(values={}){
        super();
        this.values=values;
        this.init();
    }

    set thetaLength(num){
        this.values.thetaLength=num;
        this.updateGeometry();
    }
    get thetaLength(){
        return this.values.thetaLength;
    }

    get thetaStart(){
        return this.values.thetaStart;
    }
    set thetaStart(num){
        this.values.thetaStart=num;
        this.updateGeometry();
    }

    get radius(){
        return this.values.radius;
    }
    set radius(num){
        this.values.radius=num;
        this.updateGeometry();
    }

    updateGeometry(){
        this.computeVertices();
        this.getAttribute('position').copyArray(this.vs);
        this.getAttribute('position').needsUpdate=true;
        this.getAttribute('uv').copyArray(this.us);
        this.getAttribute('uv').needsUpdate=true;
    }
    computeVertices(){
        let r=this.values.radius||2;
        let thetaStart=this.values.thetaStart||0;
        let thetaLength=this.values.thetaLength||Math.PI*2;
        let ua=thetaLength/(this.segs-1);
        for(let i=0;i<this.segs;i++){
            let x=Math.cos(thetaStart+ua*i);
            let y=Math.sin(thetaStart+ua*i);
            this.vs[i*3]=x*r;
            this.vs[i*3+1]=y*r;
            this.vs[i*3+2]=0;
            this.us[i*2]=x;
            this.us[i*2+1]=y;
        }
        this.vs[(this.segs)*3]=this.vs[(this.segs)*3+1]=this.vs[(this.segs)*3+2]=0;
        this.us[(this.segs)*2]=this.us[(this.segs)*2+1]=0;
        for(let i=0;i<this.segs*2+2;i++){
            this.us[i]=(this.us[i]+1)*0.5;
        }
        if(this.idx.length>0){
            return;
        }
        for(let i=0;i<this.segs;i++){
            this.idx[i*3]=i+1;
            this.idx[i*3+1]=this.segs;
            this.idx[i*3+2]=i;
        }
    }
    init(){
        this.initVariable();
        this.initAttribute();
    }
    initVariable(){
        this.segs=this.values.thetaSegments||36;
        this.vs=new Float32Array(this.segs*3+3);
        this.us=new Float32Array(this.segs*2+2);
        this.idx=[];
    }
    initAttribute(){
        this.computeVertices();
        this.setIndex(this.idx);
        this.setAttribute('position',new BufferAttribute(this.vs,3));
        this.setAttribute('uv',new BufferAttribute(this.us,2));
        this.setDrawRange(0,this.segs*3+3);
    }
}